package space.sakana.edusysback.service;

import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import space.sakana.edusysback.entity.Admin;
import space.sakana.edusysback.entity.User;
import space.sakana.edusysback.entity.job.*;
import space.sakana.edusysback.entity.paper.PaperItem;
import space.sakana.edusysback.mapper.AdminMapper;
import space.sakana.edusysback.mapper.UserMapper;
import space.sakana.edusysback.mapper.job.JobItemMapper;
import space.sakana.edusysback.mapper.job.JobMapper;
import space.sakana.edusysback.mapper.paper.PaperItemMapper;
import space.sakana.edusysback.result.DataResult;
import space.sakana.edusysback.result.Result;
import space.sakana.edusysback.util.CookieUtil;

import java.util.List;

@Service
public class JobService {
    private JobMapper jobMapper;
    private JobItemMapper jobItemMapper;
    private UserMapper userMapper;
    private AdminMapper adminMapper;
    private PaperItemMapper paperItemMapper;

    @Autowired
    public void autowiredMapper(JobMapper jobMapper, JobItemMapper jobItemMapper, UserMapper userMapper,
                                AdminMapper adminMapper, PaperItemMapper paperItemMapper){
        this.jobMapper = jobMapper;
        this.jobItemMapper = jobItemMapper;
        this.userMapper = userMapper;
        this.adminMapper = adminMapper;
        this.paperItemMapper = paperItemMapper;
    }

    public Result getJob(int jid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(jobMapper.selectJobById(jid)));
    }

    public Result addJob(String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        Job job = JSON.parseObject(data, Job.class);
        jobMapper.insertJob(job);
        return new DataResult(JSON.toJSONString(job));
    }

    public Result updateJob(String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        Job job = JSON.parseObject(data, Job.class);
        if (job!=null){
            return new Result(jobMapper.updateJob(job));
        }
        return Result.failResult;
    }

    public Result getJobItems(int jid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        List<JobItem> jobItems = jobItemMapper.selectJobItemsByJid(jid);
        return new DataResult(JSON.toJSONString(jobItems));
    }

    public Result addJobItem(int jid, String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        JobItem jobItem = JSON.parseObject(data, JobItem.class);
        if (jobItem!=null){
            return new Result(jobItemMapper.insertJobItem(jobItem));
        }
        return Result.failResult;
    }

    public Result updateJobItem(int jid, String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        JobItem jobItem = JSON.parseObject(data, JobItem.class);
        if (jobItem!=null){
            return new Result(jobItemMapper.updateJobItem(jobItem));
        }
        return Result.failResult;
    }

    public Result addJobTarget(int uid, int jid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        User user = userMapper.selectUserById(uid);
        if (user==null){
            return Result.failResult;
        }
        JobTarget jobTarget = jobMapper.selectJobTargetByUidAndJid(uid, jid);
        if (jobTarget!=null){
            return Result.failResult;
        }
        return new Result(jobMapper.insertJobTarget(new JobTarget(jid, user.getId())));
    }

    public Result getAllJob(HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(jobMapper.selectAllJob()));
    }

    public Result pushJob(int jid, HttpServletRequest request, HttpServletResponse response) {
        User user = userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
        if (user==null){
            return Result.failResult;
        }

        int uid = user.getId();
        JobTarget jobTarget = jobMapper.selectJobTargetByUidAndJid(uid, jid);
        if (jobTarget==null){
            return Result.failResult;
        }
        jobTarget.setPush(1);
        Job job = jobMapper.selectJobById(jobTarget.getJid());
        if (job==null){
            return Result.failResult;
        }
        JobPush jobPush = jobMapper.selectJobPushByJidAndUid(jid, uid);
        if (jobPush!=null){
            return Result.failResult;
        }
        jobPush = new JobPush(jid, uid, job.getPid());
        jobMapper.insertJobPush(jobPush);
        return new Result(jobMapper.updateJobTarget(jobTarget));
    }

    public Result pushJobItem(int jid, int pid, int qid, String answer, HttpServletRequest request, HttpServletResponse response) {
        User user = userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
        if (user==null){
            return Result.failResult;
        }

        int uid = user.getId();
        JobPushItem jobPushItem;
        jobPushItem = jobMapper.selectJobPushItem(jid, uid, qid);
        if (jobPushItem!=null){
            return Result.failResult;
        }
        jobPushItem = new JobPushItem(jid, uid, pid, qid, answer);
        return new Result(jobMapper.insetJobPushItem(jobPushItem));
    }

    public Result getWaitJob(HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        List<JobTarget> jobTargets = jobMapper.getAllWaitedJob();
        for (JobTarget jobTarget:jobTargets){
            Job job = jobMapper.selectJobById(jobTarget.getJid());
            User user = userMapper.selectUserById(jobTarget.getUid());
            List<PaperItem> paperItems = paperItemMapper.selectPaperItemByPid(job.getPid());
            int maxScore = 0;
            for (PaperItem paperItem:paperItems) {
                maxScore += paperItem.getScore();
            }
            jobTarget.setJobName(job.getName());
            jobTarget.setUserName(user.getName());
            jobTarget.setMaxScore(maxScore);
        }
        return new DataResult(JSON.toJSONString(jobTargets));
    }

    public Result getAllFinishJob(HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        List<JobTarget> jobTargets = jobMapper.selectAllFinishJobTarget();
        for (JobTarget jobTarget:jobTargets){
            Job job = jobMapper.selectJobById(jobTarget.getJid());
            User user = userMapper.selectUserById(jobTarget.getUid());
            List<PaperItem> paperItems = paperItemMapper.selectPaperItemByPid(job.getPid());
            int maxScore = 0;
            for (PaperItem paperItem:paperItems) {
                maxScore += paperItem.getScore();
            }
            int nowScore = jobMapper.selectJobPushByJidAndUid(jobTarget.getJid(), jobTarget.getUid()).getScore();
            jobTarget.setJobName(job.getName());
            jobTarget.setUserName(user.getName());
            jobTarget.setMaxScore(maxScore);
            jobTarget.setNowScore(nowScore);
        }
        return new DataResult(JSON.toJSONString(jobTargets));
    }

    public Result getPushItem(int id, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        JobTarget jobTarget = jobMapper.selectJobTarget(id);
        List<JobPushItem> jobPushItems = jobMapper.selectJobPushItemsByUidAndJid(jobTarget.getUid(), jobTarget.getJid());
        return new DataResult(JSON.toJSONString(jobPushItems));
    }

    public Result editPushItem(int id, int qid, int score, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        JobTarget jobTarget = jobMapper.selectJobTarget(id);
        JobPushItem jobPushItem = jobMapper.selectJobPushItem(jobTarget.getJid(), jobTarget.getUid(), qid);
        jobPushItem.setScore(score);
        return new Result(jobMapper.updateJobPushItemScore(jobPushItem));
    }

    public Result jobFinish(int id, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        JobTarget jobTarget = jobMapper.selectJobTarget(id);
        jobTarget.setWait(0);
        jobMapper.finishJobTarget(jobTarget);
        List<JobPushItem> jobPushItems = jobMapper.selectJobPushItemsByUidAndJid(jobTarget.getUid(), jobTarget.getJid());
        int score = 0;
        for (JobPushItem jobPushItem :jobPushItems) {
            if (jobPushItem.getScore()>0){
                score += jobPushItem.getScore();
            }
        }
        JobPush jobPush = jobMapper.selectJobPushByJidAndUid(jobTarget.getJid(), jobTarget.getUid());
        jobPush.setScore(score);
        jobMapper.updateJobPushScore(jobPush);
        return Result.successResult;
    }

    public Result deleteJob(int jid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new Result(jobMapper.deleteJobById(jid));
    }
}
